package com.qudian.pay.framework.util.mail;

import java.util.Date;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Description: 简单邮件（不带附件的邮件）发送器
 * @ClassName: SimpleMailSender
 * @author gaoxiang
 * @date 2015-1-30 下午5:38:07
 */
public class SimpleMailSender {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(SimpleMailSender.class);
	
	public static boolean sendTextMail(MailSenderInfo mailInfo) {
		// 判断是否需要身份认证
		MyAuthenticator authenticator = null;
		Properties pro = mailInfo.getProperties();
		if (mailInfo.isValidate()) {
			// 如果需要身份认证，则创建一个密码验证器
			authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
		}
		// 根据邮件会话属性和密码验证器构造一个发送邮件的session
		Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
		try {
			// 根据session创建一个邮件消息
			Message mailMessage = new MimeMessage(sendMailSession);
			// 创建邮件发送者地址
			Address from = new InternetAddress(mailInfo.getFromAddress());
			// 设置邮件消息的发送者
			mailMessage.setFrom(from);
			// 创建邮件的接收者地址，并设置到邮件消息中
			// Address to = new InternetAddress(mailInfo.getToAddress());
			Address[] to = new Address[mailInfo.getToAddress().length];
			for (int i = 0; i < to.length; i++) {
				to[i] = new InternetAddress(mailInfo.getToAddress()[i]);
			}
			mailMessage.setRecipients(Message.RecipientType.TO, to);
			// 设置邮件消息的主题
			mailMessage.setSubject(MimeUtility.encodeText(mailInfo.getSubject(),MimeUtility.mimeCharset("utf-8"), null));
			// 设置邮件消息发送的时间
			mailMessage.setSentDate(new Date());
			// 设置邮件消息的主要内容
			String mailContent = mailInfo.getContent();
			mailMessage.setText(mailContent);
			// 设置附件
			// 发送邮件
			Transport.send(mailMessage);
			return true;
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return false;
	}
	
	public static boolean sendHtmlMail(MailSenderInfo mailInfo) {
		// 判断是否需要身份认证
		MyAuthenticator authenticator = null;
		Properties pro = mailInfo.getProperties();
		// 如果需要身份认证，则创建一个密码验证器
		if (mailInfo.isValidate()) {
			authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
		}
		// 根据邮件会话属性和密码验证器构造一个发送邮件的session
		Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
		try {
			// 根据session创建一个邮件消息
			Message mailMessage = new MimeMessage(sendMailSession);
			// 创建邮件发送者地址
			Address from = new InternetAddress(mailInfo.getFromAddress());
			// 设置邮件消息的发送者
			mailMessage.setFrom(from);
			// 创建邮件的接收者地址，并设置到邮件消息中
			Address[] to = new Address[mailInfo.getToAddress().length];
			for (int i = 0; i < to.length; i++) {
				to[i] = new InternetAddress(mailInfo.getToAddress()[i]);
			}
			// Address to = new InternetAddress(mailInfo.getToAddress());
			// Message.RecipientType.TO属性表示接收者的类型为TO
			mailMessage.setRecipients(Message.RecipientType.TO, to);
			// 设置邮件消息的主题
			mailMessage.setSubject(MimeUtility.encodeText(mailInfo.getSubject(),MimeUtility.mimeCharset("utf-8"), null));
			// 设置邮件消息发送的时间
			mailMessage.setSentDate(new Date());
			// MiniMultipart类是一个容器类，包含MimeBodyPart类型的对象
			Multipart mainPart = new MimeMultipart();
			// 创建一个包含HTML内容的MimeBodyPart
			BodyPart html = new MimeBodyPart();
			// 设置HTML内容
			html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
			mainPart.addBodyPart(html);
			if (!mailInfo.getAttachFileNames().isEmpty()) {// 有附件
				Enumeration<String> efile = mailInfo.getAttachFileNames().elements();
				while (efile.hasMoreElements()) {
					// html.setFileName("=?GBK?B?"+enc.encode(affixName.getBytes())+"?=");
					html = new MimeBodyPart();
					String filename = efile.nextElement().toString(); // 选择出每一个附件名
					FileDataSource fds = new FileDataSource(filename); // 得到数据源
					html.setDataHandler(new DataHandler(fds)); // 得到附件本身并至入BodyPart
					// 这里很重要，通过下面的Base64编码的转换可以保证你的中文附件标题名在发送时不会变成乱码
					// sun.misc.BASE64Encoder enc = new
					// sun.misc.BASE64Encoder();
					html.setFileName(MimeUtility.encodeText(fds.getName(), "UTF-8", "B")); // 解决乱码,得到文件名同样至入BodyPart
					// String filenamex = html.getFileName();
					// "=?GBK?B?"+enc.encode(affixName.getBytes())+"?="
					// html.setFileName(filenamex); //得到文件名同样至入BodyPart
					mainPart.addBodyPart(html);
				}
				mailInfo.getAttachFileNames().removeAllElements();
				// 将MiniMultipart对象设置为邮件内容
			}
			mailMessage.setContent(mainPart);
			// 发送邮件
			Transport.send(mailMessage);
			return true;
		} catch (Exception ex) {
			LOGGER.error("发送邮件发生异常", ex);
		}
		return false;
	}
	
	public static boolean sendMessage(MailSenderInfo mailInfo) {
		// 判断是否需要身份认证
		MyAuthenticator authenticator = null;
		Properties pro = mailInfo.getProperties();
		// 如果需要身份认证，则创建一个密码验证器
		if (mailInfo.isValidate()) {
			authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
		}
		// 根据邮件会话属性和密码验证器构造一个发送邮件的session
		Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
		try {
			// 根据session创建一个邮件消息
			Message mailMessage = new MimeMessage(sendMailSession);
			// 创建邮件发送者地址
			Address from = new InternetAddress(mailInfo.getFromAddress());
			// 设置邮件消息的发送者
			mailMessage.setFrom(from);
			// 创建邮件的接收者地址，并设置到邮件消息中
			Address[] to = new Address[mailInfo.getToAddress().length];
			for (int i = 0; i < to.length; i++) {
				to[i] = new InternetAddress(mailInfo.getToAddress()[i]);
			}
			/**
			 * 3.设置收件人地址（可以增加多个收件人、抄送、密送），即下面这一行代码书写多行
			 * MimeMessage.RecipientType.TO:发送
			 * MimeMessage.RecipientType.CC：抄送
			 * MimeMessage.RecipientType.BCC：密送
			 */
			mailMessage.setRecipients(Message.RecipientType.TO, to);
			// 4.设置邮件主题
			mailMessage.setSubject(MimeUtility.encodeText(mailInfo.getSubject(),MimeUtility.mimeCharset("utf-8"), null));
			// 设置邮件消息发送的时间
			mailMessage.setSentDate(new Date());
			// MiniMultipart类是一个容器类，包含MimeBodyPart类型的对象
			Multipart mainPart = new MimeMultipart();
			Map<String, String> pics = mailInfo.getPics();
			if(pics != null) {
				for(Map.Entry<String, String> entry : pics.entrySet()) {
					MimeBodyPart img = new MimeBodyPart();
					// 读取本地文件
					DataHandler dh = new DataHandler(new FileDataSource(entry.getValue()));
					// 将图片数据添加到"节点"
					img.setDataHandler(dh);
					// 为"节点"设置一个唯一编号（在文本"节点"将引用该ID）
					img.setContentID(entry.getKey());
					mainPart.addBodyPart(img);
				}
			}
			// 创建一个包含HTML内容的MimeBodyPart
			MimeBodyPart html = new MimeBodyPart();
			// 设置HTML内容
			html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
			mainPart.addBodyPart(html);
			if (!mailInfo.getAttachFileNames().isEmpty()) {// 有附件
				Enumeration<String> efile = mailInfo.getAttachFileNames().elements();
				while (efile.hasMoreElements()) {
					// 5. 创建图片"节点"
					html = new MimeBodyPart();
					String filename = efile.nextElement().toString(); // 选择出每一个附件名
					FileDataSource fds = new FileDataSource(filename); // 得到数据源
					html.setDataHandler(new DataHandler(fds)); // 得到附件本身并至入BodyPart
					html.setFileName(MimeUtility.encodeText(fds.getName(), "UTF-8", "B")); // 解决乱码,得到文件名同样至入BodyPart
					mainPart.addBodyPart(html);
				}
				mailInfo.getAttachFileNames().removeAllElements();
			}
			mailMessage.setContent(mainPart);
			Transport.send(mailMessage);
			return true;
		} catch (Exception ex) {
			LOGGER.error("发送邮件发生异常", ex);
		}
		return false;
	}
}
